package com.example.sample;

import com.example.sample.ext.ColorHelper;
import com.ohos.volley.Header;
import com.ohos.volley.Request;
import com.ohos.volley.RequestQueue;
import com.ohos.volley.ext.LocalHiLog;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.colors.RgbPalette;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;

public abstract class SampleParentAbility extends Ability implements SampleInterface {

    protected static final String PROTOCOL_HTTP = "http://";
    protected static final String PROTOCOL_HTTPS = "https://";
    protected static final int LIGHTGREEN = RgbPalette.parse("#FF00FF66");
    protected static final int LIGHTRED = RgbPalette.parse("#FFFF3300");
    protected static final int YELLOW = RgbPalette.parse("#FFFFFF00");
    protected static final int LIGHTBLUE = RgbPalette.parse("#FF99CCFF");
    private static final String LOG_TAG = "SampleParentActivity";
    private static final int MENU_USE_HTTPS = 0;
    private static final int MENU_CLEAR_VIEW = 1;
    private static final int MENU_LOGGING_VERBOSITY = 2;
    private static final int MENU_ENABLE_LOGGING = 3;
    protected static String PROTOCOL = PROTOCOL_HTTPS;
    private final List<Request> requestHandles = new LinkedList<Request>();
    public DirectionalLayout customFieldsLayout;

    private TextField urlEditText, headersEditText, bodyEditText;
    protected final Component.ClickedListener onClickListener = new Component.ClickedListener() {
        @Override
        public void onClick(Component component) {
            final int id = component.getId();
            if(id == ResourceTable.Id_button_run) {
                onRunButtonPressed();
            } else if(id == ResourceTable.Id_button_cancel) {
                onCancelButtonPressed();
            } else if(id == ResourceTable.Id_button_setting) {
                boolean visible = settingLayout.getVisibility() == Component.VISIBLE;
                settingLayout.setVisibility(visible ? Component.HIDE : Component.VISIBLE);
            } else if(id == ResourceTable.Id_button_clear_outputs) {
                clearOutputs();
            } else if(id == ResourceTable.Id_button_set_logging) {
                LocalHiLog.debug("ok","ok");
            }
        }
    };
    private DirectionalLayout responseLayout;
    DirectionalLayout settingLayout;
    private boolean useHttps = true;
    private boolean enableLogging = true;

    private RequestQueue mRequestQueue;

    protected static String throwableToString(Throwable t) {
        if (t == null)
            return null;

        StringWriter sw = new StringWriter();
        t.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    }

    public static int getContrastColor(int color) {
        double y = (299 * ColorHelper.red(color) + 587 * ColorHelper.green(color) + 114 * ColorHelper.blue(color)) / 1000;
        return y >= 128 ? Color.BLACK.getValue() : Color.WHITE.getValue();
    }

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_ability_sample_parent);

        Text title = (Text) findComponentById(ResourceTable.Id_title);
        title.setText(getSampleTitle());

        urlEditText = (TextField) findComponentById(ResourceTable.Id_edit_url);
        headersEditText = (TextField) findComponentById(ResourceTable.Id_edit_headers);
        bodyEditText = (TextField) findComponentById(ResourceTable.Id_edit_body);
        customFieldsLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_layout_custom);
        Button runButton = (Button) findComponentById(ResourceTable.Id_button_run);
        Button cancelButton = (Button) findComponentById(ResourceTable.Id_button_cancel);
        Button settingButton = (Button) findComponentById(ResourceTable.Id_button_setting);
        settingLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_setting_layout);
        DirectionalLayout headersLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_layout_headers);
        DirectionalLayout bodyLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_layout_body);
        responseLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_layout_response);

        urlEditText.setText(getDefaultURL());
        headersEditText.setText(getDefaultHeaders());

        bodyLayout.setVisibility(isRequestBodyAllowed() ? Component.VISIBLE : Component.HIDE);
        headersLayout.setVisibility(isRequestHeadersAllowed() ? Component.VISIBLE : Component.HIDE);

        runButton.setClickable(true);
        runButton.setClickedListener(onClickListener);
        if (cancelButton != null) {
            if (isCancelButtonAllowed()) {
                cancelButton.setVisibility(Component.VISIBLE);
                cancelButton.setClickedListener(onClickListener);
            } else {
                cancelButton.setEnabled(false);
            }
        }
        settingButton.setClickable(true);
        settingButton.setClickedListener(onClickListener);

        Checkbox useHttpsButton = (Checkbox) findComponentById(ResourceTable.Id_button_use_https);
        Checkbox enableLoggingButton = (Checkbox) findComponentById(ResourceTable.Id_button_enable_logging);
        Button clearOutputsButton = (Button) findComponentById(ResourceTable.Id_button_clear_outputs);
        Button setLoggingButton = (Button) findComponentById(ResourceTable.Id_button_set_logging);
        clearOutputsButton.setClickable(true);
        clearOutputsButton.setClickedListener(onClickListener);
        setLoggingButton.setClickable(true);
        setLoggingButton.setClickedListener(onClickListener);

        useHttpsButton.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean checked) {
                useHttps = checked;
                PROTOCOL = useHttps ? PROTOCOL_HTTPS : PROTOCOL_HTTP;
                urlEditText.setText(getDefaultURL());
            }
        });

        enableLoggingButton.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean checked) {
                enableLogging = checked;

            }
        });

        mRequestQueue = VolleyHelper.getInstance(this).getRequestQueue();
    }

    private Object mTag = new Object();

    @Override
    public List<Request> getRequestHandles() {
        return requestHandles;
    }

    @Override
    public void addRequestHandle(Request handle) {
        if (null != handle) {
            requestHandles.add(handle);
        }
    }

    @Override
    public void onRunButtonPressed() {
        Request request = getRequest();
        Object tag = request.getTag();
        if(tag != null) {
            mTag = tag;
        }
        clearOutputs();
        mRequestQueue.add(request);
    }

    @Override
    public void onCancelButtonPressed() {
        mRequestQueue.cancelAll(mTag);
    }

    @Override
    public Map<String, String> getRequestHeaders() {
//        List<Header> headers = getRequestHeadersList();
//        return headers.toArray(new Header[headers.size()]);
        return new HashMap<>();
    }

    public String getUrlText() {
        return getUrlText(null);
    }

    public String getUrlText(String defaultText) {
        return urlEditText != null && urlEditText.getText() != null
                ? urlEditText.getText().toString()
                : defaultText;
    }

    public String getBodyText() {
        return getBodyText(null);
    }

    public String getBodyText(String defaultText) {
        return bodyEditText != null && bodyEditText.getText() != null
                ? bodyEditText.getText().toString()
                : defaultText;
    }

    public String getHeadersText() {
        return getHeadersText(null);
    }

    public String getHeadersText(String defaultText) {
        return headersEditText != null && headersEditText.getText() != null
                ? headersEditText.getText().toString()
                : defaultText;
    }

    protected final void debugHeaders(String TAG, Header[] headers) {
        if (headers != null) {
            LocalHiLog.info(TAG, "Return Headers:");
            StringBuilder builder = new StringBuilder();
            for (Header h : headers) {
                String _h = String.format(Locale.US, "%s : %s", h.getName(), h.getValue());
                LocalHiLog.info(TAG, _h);
                builder.append(_h);
                builder.append("\n");
            }
            addView(getColoredView(YELLOW, builder.toString()));
        }
    }

    protected final void debugThrowable(String TAG, Throwable t) {
        if (t != null) {
            LocalHiLog.error(TAG, "AsyncHttpClient returned error", t);
            addView(getColoredView(LIGHTRED, throwableToString(t)));
        } else {
            addView(getColoredView(LIGHTRED, "No throwable"));
        }
    }

    protected final void debugResponse(String TAG, String response) {
        if (response != null) {
            LocalHiLog.info(TAG, "Response data:");
            LocalHiLog.info(TAG, response);
            addView(getColoredView(LIGHTGREEN, response));
        } else {
            addView(getColoredView(LIGHTRED, "No response"));
        }
    }

    protected final void debugStatusCode(String TAG, int statusCode) {
        String msg = String.format(Locale.US, "Return Status Code: %d", statusCode);
        LocalHiLog.info(TAG, msg);
        addView(getColoredView(LIGHTBLUE, msg));
    }

    protected Component getColoredView(int bgColor, String msg) {
        Text tv = new Text(this);
        tv.setLayoutConfig(new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT));
        tv.setText(msg);
        ShapeElement element = new ShapeElement();
        element.setRgbColor(RgbColor.fromArgbInt(bgColor));
        tv.setBackground(element);
        tv.setPadding(10, 10, 10, 10);
        tv.setTextColor(new Color(getContrastColor(bgColor)));
        tv.setMultipleLine(true);

        return tv;
    }

    @Override
    public String getDefaultHeaders() {
        return null;
    }

    protected final void addView(Component v) {
        responseLayout.addComponent(v);
    }

    protected final void clearOutputs() {
        responseLayout.removeAllComponents();
        responseLayout.invalidate();
    }

    public boolean isCancelButtonAllowed() {
        return false;
    }

}
